﻿using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Net;
using System.IO;
using Microsoft.Win32;
using System.Threading;

namespace ClientPolicy
{
    public partial class ClientPolicy : Form
    {
        public ClientPolicy()
        {
            InitializeComponent();           
        }

        private IntPtr thisWindow;
        private Hotkey hotkey;

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(String sClassName, String sAppName);

      
        [DllImport("user32.dll")]
        public static extern int SetForegroundWindow(
            int hWnd // handle to window
         );

        public bool Login = false;
        bool Run = true;
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Login = false;
            ClientLogin frm = new ClientLogin();
            frm.Owner = this;
            frm.ShowDialog();

            if (Login)
                this.Show();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {           
            KillTaskManager.Enabled = true;
            Run = true;
            this.Hide();
        }

        private void KillTaskManager_Tick(object sender, EventArgs e)
        {
            try
            {
                KillTaskManager.Enabled = false;
                foreach (Process proc in Process.GetProcessesByName("Taskmgr"))
                {
                    proc.Kill();
                }
                               
            }
            catch
            { }
            finally { KillTaskManager.Enabled = true; }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            Run = false;
            KillTaskManager.Enabled = false;
        }

        // device state change
        private const int WM_DEVICECHANGE = 0x0219;

        // logical volume(A disk has been inserted, such a usb key or external HDD)
        private const int DBT_DEVTYP_VOLUME = 0x00000002;

        // detected a new device
        private const int DBT_DEVICEARRIVAL = 0x8000;

        // preparing to remove
        private const int DBT_DEVICEQUERYREMOVE = 0x8001;

        // removed
        private const int DBT_DEVICEREMOVECOMPLETE = 0x8004;

        enum Permission { Allow = 3, Deny = 4 };
        public bool isHide = true;
        bool closeExplorer = true;
        bool ico = true;
        protected override void WndProc(ref Message message)
        {
            bool loadPolicy = true;
            if (message.Msg == 0x0312)
            {
               // isHide = false;
                if (message.WParam == (IntPtr)1)
                {

                    ico = false;
                    notifyIcon1.Visible = true;
                }
                if (message.WParam == (IntPtr)2)
                {
                    ico = true;
                    notifyIcon1.Visible = false;
                }
                //this.Show();
            }
           base.WndProc(ref message);
            if (isHide)
            {
                if(ico)
                  notifyIcon1.Visible = false;
             
                this.Hide();
                KillTaskManager.Enabled = true;
            }
            if ((message.Msg != WM_DEVICECHANGE) || (message.LParam == IntPtr.Zero))
                return;

            DEV_BROADCAST_VOLUME volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(message.LParam, typeof(DEV_BROADCAST_VOLUME));

            if (volume.dbcv_devicetype == DBT_DEVTYP_VOLUME)
            {
                switch (message.WParam.ToInt32())
                {
                    // New device inserted...
                    case DBT_DEVICEARRIVAL:
                        {
                           closeExplorer = true;
                            // MessageBox.Show(
                          // string.Format("A storage device has been inserted; Drive :{0}", ToDriveName(volume.dbcv_unitmask)), "Detect USB");
                            if (Run)
                            {
                                loadPolicy = loadPolicyUSB();
                                if (loadPolicy==false)
                                {
                                    while (closeExplorer)
                                    {
                                        ExploreStop();
                                        Application.DoEvents();
                                    }
                                    
                                }
                            }
                        }
                        break;

                    // Device Removed.
                    case DBT_DEVICEREMOVECOMPLETE:
                        {
                            //MessageBox.Show("Storage has been removed.", "Detect USB");
                            if (Run)
                            {
                                  closeExplorer = false;
                                    ExploreStart();
                                    
                            }
                        }
                        break;
                }
                
            }
            // hotkey
            //if (message.Msg == WM_HOTKEY && (int)message.WParam == 1)
            //{
            //    MessageBox.Show("here");
            //}
                      
        }
        const int WM_HOTKEY = 0x0312;
        private string ToDriveName(int mask)
        {
            int offset = 0;
            while ((offset < 26) && ((mask & 0x00000001) == 0))
            {
                mask = mask >> 1;
                offset++;
            }

            if (offset < 26)
                return String.Format("{0}:", Convert.ToChar(Convert.ToInt32('A') + offset));

            return "?";
        }

        // Contains information about a logical volume.
        [StructLayout(LayoutKind.Sequential)]
        private struct DEV_BROADCAST_VOLUME
        {
            public int dbcv_size;
            public int dbcv_devicetype;
            public int dbcv_reserved;
            public int dbcv_unitmask;
        }


        private void ExploreStop()
        {
            try
            {              
           
                 Process[] prs = Process.GetProcesses();
                 foreach (Process pr in prs)
                 {
                             if (pr.ProcessName == "explorer")
                              pr.Kill();
                             else  if (pr.ProcessName == "iexplorer")
                                   pr.Kill();
                              else  if (pr.ProcessName == "chrome")
                                 pr.Kill();
                             else if (pr.ProcessName == "firefox")
                                 pr.Kill();
                             else if (pr.ProcessName == "safari")
                                 pr.Kill();
                             else if (pr.ProcessName == "opera")
                                 pr.Kill();
                             else if (pr.ProcessName == "cmd")
                                 pr.Kill();
                 }
            }
            catch
            { }           
        }

        private void ExploreStart()
        {
            System.Diagnostics.Process.Start(@"C:\Windows\explorer.exe");
        }


        private bool loadPolicyUSB()
        {
            try
            {
                string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
                string[] cutusername = userName.Split('\\');
                IPHostEntry host = new IPHostEntry();
                string localIP = "?";
                host = Dns.GetHostEntry(Dns.GetHostName());
                foreach (IPAddress ip in host.AddressList)
                {
                    if (ip.AddressFamily.ToString() == "InterNetwork")
                    {
                        localIP = ip.ToString();
                    }
                }
                WebBrowser wb = new WebBrowser();
                string iplan = localIP;
                string link = "http://192.168.1.15:90/GetInfo.aspx?tk=" + cutusername[1].ToString().ToLower() + "&policy=usb&pc=" + cutusername[0].ToString().ToLower() + "&ip=" + iplan;
                wb.Navigate(link);
                while (wb.ReadyState != WebBrowserReadyState.Complete)
                {
                    Application.DoEvents();
                    System.Threading.Thread.Sleep(50);
                }
                string kq = wb.DocumentText;
                if (kq.Contains("USB:1"))
                {
                    return true;
                }
            }
            catch
            {
                return false;
            }
            return false;
        }

        private Thread serverThread;
        private Thread serverThread1;

        private void AutoCheckUpdate_Tick(object sender, EventArgs e)
        {
           
                serverThread = new Thread(new ThreadStart(CheckUpdate));
                serverThread.Start();
           
        }
        private void CheckUpdate()
        {           
             AutoCheckUpdate.Enabled = false;
            try
            {
                Application.DoEvents();
                string v = Application.ProductVersion;

                WebClient wc = new WebClient();
                wc.Headers.Add("Cache-Control", "no-cache");
                string newver = wc.DownloadString(@"http://hfc.lbc.com.vn/tool/update/it/ClientPolicy.txt").Trim();
                newver = newver.Replace("\"", "");

                if (v != newver)
                {
                    this.Close();
                    if (File.Exists(@"ClientPolicyUpdate.exe"))
                    {
                        System.Diagnostics.Process.Start(@"ClientPolicyUpdate.exe");
                    }
                }

            }
            catch { }
            finally { AutoCheckUpdate.Enabled = true; }       
        }

        private void ClientPolicy_Load(object sender, EventArgs e)
        {
            try
            {
                //foreach (Process proc in Process.GetProcessesByName("ClientPolicy"))
                //{
                //   Application.Exit();                   
                //}

                if (!File.Exists(@"ClientPolicyUpdate.exe"))
                {
                    downloadData("ClientPolicyUpdate.exe");
                    saveData("ClientPolicyUpdate.exe", 0);
                }
                SetStartup();
                Online.Enabled = true;
                string v = Application.ProductVersion;
                notifyIcon1.Text = "Client Policy "+v.Replace('"',' ');

               // this.Handle
                thisWindow = FindWindow(null, "Client Policy"); //(IntPtr)this.Handle; //
                hotkey = new Hotkey(thisWindow);
                hotkey.RegisterHotKeys();
            }
            catch { }
            
            AutoCheckUpdate.Enabled = true;     
  
        }

        private byte[] downloadedData;
        //Connects to a URL and attempts to download the file
        int bytebuffer = 1024; //set cai nay de tang toc do down.
        private void downloadData(string url)
        {
            string Link = "http://hfc.lbc.com.vn/tool/update/it/";
            url = Link + url;           
            downloadedData = new byte[0];
            try
            {
                //Optional
                this.Text = "Connecting...";
                Application.DoEvents();

                //Get a data stream from the url
                WebRequest req = WebRequest.Create(url);
                WebResponse response = req.GetResponse();
                Stream stream = response.GetResponseStream();

                //Download in chuncks
                byte[] buffer = new byte[bytebuffer]; // old [1024]

                //Get Total Size
                int dataLength = (int)response.ContentLength;

                //With the total data we can set up our progress indicators

                this.Text = "Downloading...";
                Application.DoEvents();
                //Download to memory
                //Note: adjust the streams here to download directly to the hard drive
                MemoryStream memStream = new MemoryStream();
                while (true)
                {
                    //Try to read the data
                    int bytesRead = stream.Read(buffer, 0, buffer.Length);

                    if (bytesRead == 0)
                    {
                        //Finished downloading

                        Application.DoEvents();
                        break;
                    }
                    else
                    {
                        //Write the downloaded data
                        memStream.Write(buffer, 0, bytesRead);

                        //Update the progress bar
                      
                    }
                }

                //Convert the downloaded stream to a byte array
                downloadedData = memStream.ToArray();

                //Clean up
                stream.Close();
                memStream.Close();
            }
            catch (Exception)
            {
               
            }

            
        }
        private void saveData(string fileName, int exit)
        {
            if (downloadedData != null && downloadedData.Length != 0)
            {
                this.Text = "Saving Data...";
                Application.DoEvents();

                //Write the bytes to a file
                FileStream newFile = new FileStream(@fileName, FileMode.Create);
                newFile.Write(downloadedData, 0, downloadedData.Length);
                newFile.Close();
                this.Text = "Download Data";
                // MessageBox.Show("Saved Successfully");
                if (exit == 1)
                {
                    this.Close();
                }
            }
        }

        private void SetStartup()
        {
            RegistryKey rk = Registry.CurrentUser.OpenSubKey
                ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);          
                rk.SetValue("ClientPolicy", Application.ExecutablePath.ToString());           

        }

        private void Online_Tick(object sender, EventArgs e)
        {
           
                serverThread1 = new Thread(new ThreadStart(OnlineLoad));
                serverThread1.Start();
           
        }
        private void OnlineLoad()
        {
            Online.Enabled = false;
            try
            {
                Application.DoEvents();
                string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
                string[] cutusername = userName.Split('\\');
                IPHostEntry host = new IPHostEntry();
                string localIP = "?";
                host = Dns.GetHostEntry(Dns.GetHostName());
                foreach (IPAddress ip in host.AddressList)
                {
                    if (ip.AddressFamily.ToString() == "InterNetwork")
                    {
                        localIP = ip.ToString();
                    }
                }
                string iplan = localIP;
                string link = "http://192.168.1.15:90/GetInfo.aspx?tk=" + cutusername[1].ToString().ToLower() + "&online=usb&pc=" + cutusername[0].ToString().ToLower() + "&ip=" + iplan;
                WebClient wc = new WebClient();
                wc.Headers.Add("Cache-Control", "no-cache");
                wc.DownloadString(link);

            }
            catch { }
            finally { Online.Enabled = true; }
        }

        private void ClientPolicy_KeyDown(object sender, KeyEventArgs e)
        {
           
        }

        private void ClientPolicy_FormClosing(object sender, FormClosingEventArgs e)
        {
            hotkey.UnRegisterHotKeys();
        }

        //protected override void WndProc(ref Message keyPressed)
        //{
        //    if (keyPressed.Msg == 0x0312)
        //    {
        //        this.Show();
        //    }
        //    base.WndProc(ref keyPressed);
        //}
    }
}
